package com.bestcem.xm.user.service.impl;

import cn.hutool.core.lang.ObjectId;
import com.bestcem.xm.common.core.domain.web.ServiceResult;
import com.bestcem.xm.common.core.enums.ReqErrorCodeEnum;
import com.bestcem.xm.common.core.enums.ResourceErrorCodeEnum;
import com.bestcem.xm.user.config.properties.UserEmailProperties;
import com.bestcem.xm.user.dao.UserSmtpDao;
import com.bestcem.xm.user.entity.pojo.UserSmtpDO;
import com.bestcem.xm.user.enums.BooleanStatusEnum;
import com.bestcem.xm.user.enums.UserEnum;
import com.bestcem.xm.user.enums.UserSmtpValidateStatusEnum;
import com.bestcem.xm.user.mq.send.biz.UserMessageSendService;
import com.bestcem.xm.user.service.UserSmtpService;
import com.bestcem.xm.user.service.dto.PageRequestDTO;
import com.bestcem.xm.user.service.dto.PageResponseDTO;
import com.bestcem.xm.user.service.dto.user.UserSmtpDTO;
import com.bestcem.xm.user.util.convert.UserSmtpConvert;
import com.bestcem.xm.user.util.converter.sort.UserSmtpSortNameConverter;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 邮箱配置服务
 *
 * @author qiongyu.cui <qiongyu.cui@idiaoyan.com>
 * @version v1.0
 * @date 2022/3/16 11:30
 */
@Service
public class UserSmtpServiceImpl implements UserSmtpService {

    @Autowired
    private UserEmailProperties userEmailProperties;

    @Resource
    private UserSmtpDao userSmtpDao;

    @Resource
    private UserSmtpConvert userSmtpConvert;

    //@Resource
    //private UserSmtpMessageSender userSmtpMessageSender;

    @Resource
    private UserMessageSendService userMessageSendService;

    @Override
    public ServiceResult<PageResponseDTO<UserSmtpDTO>> listByPage(PageRequestDTO page, String orgId, List<Integer> validateStatus) {
        // 参数校验
        if (Objects.isNull(page.getPage()) || Objects.isNull(page.getSize())) {
            return ServiceResult.fail(ReqErrorCodeEnum.PARAM_LOST, "分页大小和第几页都不能为空！");
        }
        ServiceResult<String> checkSortBy = UserSmtpSortNameConverter.checkAndConvertSortName(page.getSortBy());
        if (!checkSortBy.isSuccess()) {
            return ServiceResult.fail(ReqErrorCodeEnum.PARAM_RANGE, "指定的排序字段不正确");
        }
        page.setSortBy(checkSortBy.getData());

        PageResponseDTO<UserSmtpDTO> result = new PageResponseDTO<>();
        // 根据条件查询相关总数
        Long count = userSmtpDao.count(orgId, validateStatus);
        result.setTotal(count);
        result.setPage(page.getPage());
        if (count == 0) {
            return ServiceResult.success(result);
        }

        // 分页查询相关内容
        List<UserSmtpDO> smtpDOList = userSmtpDao.listByPage(page.getPage(), page.getSize(), page.getDescending(), page.getSortBy(), orgId, validateStatus);
        result.setRows(userSmtpConvert.dos2Dtos(smtpDOList));
        return ServiceResult.success(result);
    }

    @Override
    public ServiceResult<List<UserSmtpDTO>> listSmtp(String orgId, Boolean descending, String sortBy, List<Integer> validateStatus) {
        // 校验参数
        ServiceResult<String> checkSortBy = UserSmtpSortNameConverter.checkAndConvertSortName(sortBy);
        if (!checkSortBy.isSuccess()) {
            return ServiceResult.fail(ReqErrorCodeEnum.PARAM_RANGE, "指定的排序字段不正确");
        }
        sortBy = checkSortBy.getData();

        // 根据条件查询相关总数
        Long count = userSmtpDao.count(orgId, validateStatus);
        Integer size = count > 10000 ? 10000 : count.intValue();
        List<UserSmtpDO> smtpDOList = userSmtpDao.listByPage(1, size, descending, sortBy, orgId, validateStatus);
        return ServiceResult.success(userSmtpConvert.dos2Dtos(smtpDOList));
    }

    @Override
    public ServiceResult<UserSmtpDTO> selectById(String smtpId) {
        UserSmtpDO userSmtpDO = userSmtpDao.selectById(smtpId);
        return ServiceResult.success(userSmtpConvert.do2Dto(userSmtpDO));
    }

    @Override
    public ServiceResult<List<UserSmtpDTO>> selectBySelective(UserSmtpDTO userSmtpDTO) {
        List<UserSmtpDO> userSmtpDos = userSmtpDao.selectBySelective(userSmtpConvert.dto2Do(userSmtpDTO));
        return ServiceResult.success(userSmtpConvert.dos2Dtos(userSmtpDos));
    }

    @Override
    public ServiceResult<UserSmtpDTO> selectByIdAndOrgId(String smtpId, String orgId) {
        UserSmtpDO userSmtpDO = new UserSmtpDO();
        userSmtpDO.setSmtpId(smtpId);
        userSmtpDO.setOrgId(orgId);
        List<UserSmtpDO> userSmtpDOList = userSmtpDao.selectBySelective(userSmtpDO);
        if (CollectionUtils.isEmpty(userSmtpDOList)) {
            return ServiceResult.fail(ResourceErrorCodeEnum.NOT_FOUND, "未查询到对应的邮箱配置信息");
        }
        return ServiceResult.success(userSmtpConvert.do2Dto(userSmtpDOList.get(0)));
    }

    @Override
    public ServiceResult<Boolean> updateByIdAndOrgId(String smtpId, String orgId, UserSmtpDTO userSmtpDto) {
        Integer result = userSmtpDao.updateSelectiveByIdAndOrgId(smtpId, orgId, userSmtpConvert.dto2Do(userSmtpDto));
        return ServiceResult.success(result.equals(1));
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public ServiceResult<String> createSmtp(String orgId, UserSmtpDTO dto) {
        // 如果设置默认邮箱，需要把其他的默认邮箱设置为非默认
        updateDefaultSmtp(orgId, dto);

        // 添加邮箱设置
        UserSmtpDO createDo = userSmtpConvert.dto2Do(dto);
        createDo.setOrgId(orgId);
        String smtpId = userSmtpDao.insertSelective(createDo);
        return ServiceResult.success(smtpId);
    }

    @Override
    public ServiceResult<String> insertSelective(UserSmtpDTO dto) {
        String smtpId = userSmtpDao.insertSelective(userSmtpConvert.dto2Do(dto));
        return ServiceResult.success(smtpId);
    }

    /**
     * 设置默认邮箱，需要把其他的默认邮箱设置为非默认
     *
     * @param orgId 公司id
     * @param dto   接口入参
     * @return void
     * @author panyun <yun.pan@idiaoyan.com>
     * @date 2022/3/17 20:14
     */
    private void updateDefaultSmtp(String orgId, UserSmtpDTO dto) {
        UserSmtpDO smtpDO = new UserSmtpDO();
        smtpDO.setOrgId(orgId);
        boolean needUpdate = false;
        if (UserEnum.USER_YES.getFlag().equals(dto.getDeliverFlag())) {
            smtpDO.setDeliverFlag(UserEnum.USER_NO.getFlag());
            needUpdate = true;
        }
        if (UserEnum.USER_YES.getFlag().equals(dto.getNoticeFlag())) {
            smtpDO.setNoticeFlag(UserEnum.USER_NO.getFlag());
            needUpdate = true;
        }
        if (needUpdate) {
            userSmtpDao.updateSelectiveByOrgId(smtpDO);
        }
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public ServiceResult<String> updateSmtp(String orgId, UserSmtpDTO dto) {
        UserSmtpDO userSmtpDO = new UserSmtpDO();
        userSmtpDO.setOrgId(orgId);
        if (StringUtils.isNotBlank(dto.getAccount())) {
            userSmtpDO.setAccount(dto.getAccount());
            List<UserSmtpDO> dos = userSmtpDao.selectBySelective(userSmtpDO);
            List<UserSmtpDO> collect = dos.stream().filter(t -> !dto.getSmtpId().equals(t.getSmtpId())).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(collect)) {
                return ServiceResult.fail(ReqErrorCodeEnum.PARAM_RANGE, "邮箱账户已存在");
            }
        }

        UserSmtpDO smtpDO = userSmtpDao.selectById(dto.getSmtpId());
        if (Objects.isNull(smtpDO)) {
            return ServiceResult.fail(ReqErrorCodeEnum.PARAM_RANGE, String.format("smtpId:%s不正确", dto.getSmtpId()));
        }

        updateDefaultSmtp(orgId, dto);

        // 更新操作
        Integer row = userSmtpDao.updateSelectiveByIdAndOrgId(dto.getSmtpId(), orgId, userSmtpConvert.dto2Do(dto));
        if (row == 0) {
            return ServiceResult.fail(ReqErrorCodeEnum.PARAM_RANGE, "更新失败");
        }

        return ServiceResult.success(dto.getSmtpId());
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public ServiceResult<Integer> deleteSmtpByIds(String orgId, List<String> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return ServiceResult.fail(ReqErrorCodeEnum.PARAM_LOST, "需要删除的邮箱id列表不能为空");
        }
        // 校验格式
        for (String id : ids) {
            if (!ObjectId.isValid(id)) {
                return ServiceResult.fail(ReqErrorCodeEnum.PARAM_RANGE, "邮箱id列表格式不正确");
            }
        }

        Integer row = userSmtpDao.deleteByIds(ids, orgId);

        //发送mq消息
        userMessageSendService.publishSmtpDelete(ids);

        setSystemSmtpIsNotice(orgId);

        return ServiceResult.success(row);
    }

    public void setSystemSmtpIsNotice(String orgId) {
        // 当删除了发件箱，需要检查还有默认发件箱。没有默认发件箱，设置系统发件箱为默认发件箱
        UserSmtpDO smtpDO = new UserSmtpDO();
        smtpDO.setOrgId(orgId);
        smtpDO.setNoticeFlag(BooleanStatusEnum.YES.getStatus());
        List<UserSmtpDO> smtpDOS = userSmtpDao.selectBySelective(smtpDO);
        if (CollectionUtils.isEmpty(smtpDOS)) {
            UserSmtpDO smtp = new UserSmtpDO();
            smtpDO.setOrgId(orgId);
            smtpDO.setSystemFlag(BooleanStatusEnum.YES.getStatus());
            List<UserSmtpDO> userSmtpDOS = userSmtpDao.selectBySelective(smtp);
            if (CollectionUtils.isEmpty(userSmtpDOS)) {
                UserSmtpDO updateSystem = new UserSmtpDO();
                smtpDO.setSmtpId(userSmtpDOS.get(0).getSmtpId());
                smtpDO.setNoticeFlag(BooleanStatusEnum.YES.getStatus());
                userSmtpDao.updateSelectiveById(updateSystem);
            }
        }
    }

    @Override
    public ServiceResult<Integer> deleteBySelective(UserSmtpDTO userSmtpDTO) {
        Integer row = userSmtpDao.deleteBySelective(userSmtpConvert.dto2Do(userSmtpDTO));
        return ServiceResult.success(row);
    }

    @Override
    public ServiceResult<String> createSystemSmtp(String orgId, String smtpId) {
        UserSmtpDTO dto = new UserSmtpDTO();
        dto.setAccount(userEmailProperties.getDefaultEmail())
                .setPassword(userEmailProperties.getDefaultPwd())
                .setHost(userEmailProperties.getDefaultHost())
                .setPort(userEmailProperties.getDefaultPort())
                .setDescription("倍市得系统邮箱")
                .setSslFlag(UserEnum.USER_YES.getFlag())
                .setValidateStatus(UserSmtpValidateStatusEnum.VERIFIED_SUCCESS.getStatus())
                .setDeliverFlag(UserEnum.USER_NO.getFlag())
                .setNoticeFlag(UserEnum.USER_YES.getFlag())
                .setSystemFlag(UserEnum.USER_YES.getFlag())
                .setSmtpId(smtpId)
                .setOrgId(orgId);
        return this.insertSelective(dto);
    }
}
